package com.pisolution.scheduler.runtime.worker.reporter;

import com.pisolution.scheduler.core.utils.Stopper;
import com.pisolution.scheduler.runtime.worker.cache.ResponseCache;
import com.pisolution.scheduler.runtime.worker.processor.TaskCallbackService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 可重试任务状态汇报器 用于发送缓存中的确认指令与响应指令给管理节点.
 *
 * @author sora
 * @version 0.1.0
 */
@Component
public class TaskStateReporter implements Runnable {
    private static final Logger LOGGER = LoggerFactory.getLogger(TaskStateReporter.class);

    // -------------------------------------------------------------------------------------------------

    /** 用于发送交互指令给管理节点. */
    private final TaskCallbackService service;

    /** 用于访问缓存的交互指令. */
    private final ResponseCache cache;

    // -------------------------------------------------------------------------------------------------
    //  初始化
    // -------------------------------------------------------------------------------------------------

    public TaskStateReporter(final TaskCallbackService service, final ResponseCache cache) {
        this.service = service;
        this.cache = cache;
    }

    // -------------------------------------------------------------------------------------------------
    //  生命周期
    // -------------------------------------------------------------------------------------------------

    /**
     * 启动汇报器.
     */
    public void start() {
        final Thread thread = new Thread(this, "task-state-reporter");

        thread.start();
    }

    @SuppressWarnings("BusyWait")
    @Override
    public void run() {
        while (Stopper.isRunning()) {
            // 1. 设定发送间隔.
            try {
                Thread.sleep(300_000L);
            } catch (InterruptedException ignored) {
                // 无需处理此问题.
            }

            try {
                // 2. 如果有待发送的确认指令则发送确认指令.
                if (!this.cache.getAck().isEmpty()) {
                    this.cache.getAck().forEach(this.service::sendAck);
                }

                // 3. 如果有待发送的响应指令则发送响应指令.
                if (!this.cache.getResponse().isEmpty()) {
                    this.cache.getResponse().forEach(this.service::sendResult);
                }
            } catch (Exception e) {
                LOGGER.warn("Could not report the state of the cached task.", e);
            }
        }
    }
}
